<?php

namespace App\Services\Authcode\Authcode;

use Illuminate\Support\Facades\DB;
use App\Models\Authcode\Authcode;
use App\Services\Authcode\ValidateAuthcode;
use Gregwar\Captcha\CaptchaBuilder;

class AuthcodeLogic
{

    //检测该验证码信息是否存在
    public function checkRepeat($data)
    {
        $_where['token']   = $data['token'];
        $_where['type']    = $data['type'];
        $_where['code_id'] = $data['code_id'];

        $findRes = Authcode::where($_where)->first();
        if (!empty($findRes)) {
            return $this->updateAuthCode($data,$findRes['id']);
        }
        return $this->createAuthCode($data);
    }

    /**
     * 创建验证码
     * @param $data
     * @return array
     */
    public function createAuthCode($data)
    {
        $security = $this->makeCapche($data);
        $data = delete_code_config($data);
        $data['auth_code'] = $security['authcode'];
        $data['code_base64'] = base64_encode($security['dataflow']);
        $data['create_time'] = time();

        $rst  = Authcode::insert($data);
        if ($rst == false) {
            return auto_failure ($data,'验证码生成失败！');
        } elseif ($rst === 0) {
            return auto_failure ($data,'验证码未生成！');
        }
        return auto_return(['code_base64' => $data['code_base64']],'验证码生成成功！');
    }

    /**
     * 更新验证码
     * @param $data
     * @param $id
     * @return array
     */
    public function updateAuthCode($data, $id)
    {
        $security = $this->makeCapche($data);
        $data = delete_code_config($data);
        $data['auth_code'] = $security['authcode'];
        $data['code_base64'] = base64_encode($security['dataflow']);
        $data['update_time'] = time();

        $rst  = Authcode::where('id', $id)->update($data);
        if ($rst == false) {
            return auto_failure ($data,'验证码刷新失败！');
        }
        return auto_return(['code_base64' => $data['code_base64']],'验证码刷新成功！');
    }

    //验证验证码
    public function verifyAuthCode($data)
    {
        # 显式数据验证
        //ValidateAuthcode::checkValidate($data, ["type","code_id","auth_code"]);

        $exist = $this->verifyExist($data);
        if ($exist == false) {
            return auto_failure(['verify' => false],"该图形验证码不存在，请重试！");
        }
        $verifyRes = $this->deleteCode($data);
        if ($verifyRes == false) {
            return auto_failure(['verify' => false],"超过验证次数或验证超时，请重试！");
        }
        $findRes = \App\Models\Authcode\Authcode::where($data)->first();
        if ($findRes == null) {
            $this->addNum($data);
            return auto_failure(['verify' => false],"图形验证码不正确，请重试！");
        }

        \App\Models\Authcode\Authcode::destroy($findRes['id']);
        return auto_return(['verify' => true],"图形验证码正确！");
    }

    //验证 验证码是否存在;
    private function verifyExist($data)
    {
        unset($data['auth_code']);
        $findArr = \App\Models\Authcode\Authcode::where($data)->first();
        if ($findArr == null) {
            return false;
        }
        return true;
    }

    // 验证码试错次数超过5或超过30分钟 删除验证码;
    private function deleteCode($data)
    {
        unset($data['auth_code']);

        $findArr = \App\Models\Authcode\Authcode::where($data)->first();
        $verifyTime = $findArr['create_time'] + 1800;
        $current = time();
        if ($findArr['nums'] >= 5 || $current > $verifyTime) {
            \App\Models\Authcode\Authcode::destroy($findArr['id']);
            return false;
        }
        return true;
    }

    // 验证码试错次数 +1;
    private function addNum($data)
    {
        unset($data['auth_code']);
        $findArr = \App\Models\Authcode\Authcode::where($data)->first();
        $nums['nums'] = $findArr['nums'] + 1;
        \App\Models\Authcode\Authcode::where("id", $findArr["id"])->update($nums);
    }

    public function makeCapche($data)
    {
        $config = code_config($data);
        $builder = new CaptchaBuilder($data['length']);
        $pic = $builder->build($width = $config['imageW'], $height = $config['imageH'])->get();
        return ['authcode'  => $builder->getPhrase(), 'dataflow' => $pic];
    }
}